package unimelb.distSystems.project2;

/*
 * Lim Ching Lih, 308721
 * Yu Xia, 351025
 * Carlos Vasconcelos, 193554
 */

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.net.InetAddress;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

import unimelb.distSystems.communications.CORBA.GameService;
import unimelb.distSystems.game.GameEngine;

/*
 * Game window frame for human interactions
 */
public class Game extends JFrame{	
	//Screen objects
	private LoginScreen login_gui=null;
	private MenuScreen menu_gui=null;
	private CreateAccountScreen createaccount_gui=null;
	private HostRoomScreen host_gui=null;
	private MatchRoomScreen matchroom_gui=null;
	
	//Static codes for screen types
	public static final int LOGIN_SCREEN=1;
	public static final int MENU_SCREEN=2;
	public static final int CREATEACCOUNT_SCREEN=3;
	public static final int HOST_SCREEN=4;
	public static final int MATCHROOM_SCREEN=5;
	
	//Window variables
	private GUIScreen current_screen=null;
	private Player current_player=null;
	private MatchRoom current_matchroom=null;
	
	//Others
	private GameClient gameClient;
    private GameService gameService;
    private GameEngine game;

	//TEMP
	public static void main(String[] args) {
		String address=Configurations.host;//Default value
    	int port_no=Configurations.port_number;//Default value
    	
    	if(args.length==2)
    	{
    		address=args[0];
    		port_no=Integer.parseInt(args[1]);
    		System.out.println("Read: "+address+", "+port_no);
    	}
		
		Game client = new Game();
		client.initialiseGUI();
		client.start(address,port_no);
		
		try{
			InetAddress addr = InetAddress.getLocalHost();
			System.out.println("Client application is up ("+addr.getHostAddress()+
					" connects to server "+address+":"+port_no+")");
		}catch(Exception e){e.printStackTrace();}
				
		client.show();
	}
	
	/*
	 * Set of actions to do when being displayed for first time
	 */
	public void start(String address,int port_no)
	{
		gameClient = new GameClient(this,address,port_no);
		go_to_screen(LOGIN_SCREEN);		
	}
	
	/*
	 * Initialize the window frame
	 */
	public void initialiseGUI()
	{
		try {
			setIconImage(ImageIO.read(new File(Configurations.app_icon)));
		} catch (Exception e) {
			System.out.println("ERROR: '"+Configurations.app_icon+"' is not readable!");
		}
		setTitle(Configurations.title);
		setSize(Configurations.appScreenWidth,Configurations.appScreenHeight);
		setResizable(false);
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent winEvt) {perform_exit_operation();}
		});	    
		
		//Center frame
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		setLocation((screenSize.width/2)-(Configurations.appScreenWidth/2),
					(screenSize.height/2)-(Configurations.appScreenHeight/2));
	}
	
	/*
	 * Change current screen to requested screen
	 * Input: int Code for required screen
	 * Output: Nothing
	 */
	public void go_to_screen(int screen_type)
	{
		//clear the window frame
		getContentPane().removeAll();
		
		if(current_screen!=null)
			current_screen.perform_actions_prior_exit();
			//Before being swapped out, do actions required first
		
		/*
		 * Select the screen object reference
		 */
		if(screen_type==LOGIN_SCREEN)
		{
			if(login_gui==null)
				login_gui = new LoginScreen(this);
		
			current_screen=login_gui;
		}
		else if(screen_type==MENU_SCREEN)
		{
			if(menu_gui==null)
				menu_gui = new MenuScreen(this);

			current_screen=menu_gui;
		}
		else if(screen_type==CREATEACCOUNT_SCREEN)
		{
			if(createaccount_gui==null)
				createaccount_gui = new CreateAccountScreen(this);

			current_screen=createaccount_gui;
		}
		else if(screen_type==HOST_SCREEN)
		{
			if(host_gui==null)
				host_gui = new HostRoomScreen(this);

			current_screen=host_gui;
		}
		else if(screen_type==MATCHROOM_SCREEN)
		{
			if(matchroom_gui==null)
				matchroom_gui = new MatchRoomScreen(this);

			current_screen=matchroom_gui;
		}
		else
		{
			System.out.print("ERROR: Trying to load an unknown screen - "+screen_type);
			return;
		}
		
		//Before displaying the requested screen, do actions required first
		current_screen.perform_actions_prior_display();
		
		//Pass reference of window frame for the screen to load its components
		current_screen.display(getContentPane());
		
		//Force fresh screen rendering
		getContentPane().validate();
		getContentPane().repaint();
	}
	
	/*
	 * Do actions prior to program exit
	 * frame.addWindowListener() will invoke this method when human clicks big X button or game exit button
	 */
	public void perform_exit_operation()
	{
		int choice=JOptionPane.showConfirmDialog(this,"Quit this game?","Exit",
							JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE);
		if(choice==JOptionPane.NO_OPTION)
			return;
		
		//Actions to perform before exiting
		if(current_matchroom!=null)
			current_screen.perform_actions_prior_exit();
		
		System.exit(0);//BYE BYE
	}
	
	/*
	 * Cache the copy of the Player instance for later references
	 */
	public void cache_player(Player player)
	{
		current_player=player;
	}
	
	/*
	 * Return reference of the cached copy of the Player instance
	 */
	public Player get_current_player()
	{
		return current_player;
	}
	
	/*
	 * Cache the copy of the MatchRoom instance for later references
	 */
	public void cache_match_room(MatchRoom this_room)
	{
		current_matchroom=this_room;
	}
	
	/*
	 * Return reference of the cached copy of the MatchRoom instance
	 */
	public MatchRoom get_current_matchroom()
	{
		return current_matchroom;
	}
	
	/*
	 * Access methods to variables required for COBRA communications
	 */
    public void setGameClient(GameClient client){
        gameClient=client;
    }

    public GameClient getGameClient(){
        return gameClient;
    }

    public GameService getGameService() {
        return gameService;
    }

    public void setGameService(GameService gameService) {
        this.gameService = gameService;
    }
    
    public MatchRoomScreen getMatchroom_gui() {
        return matchroom_gui;
    }

    public GUIScreen getCurrent_screen() {
        return current_screen;
    }

    public GameEngine getGame() {
        return game;
    }

    public void setGame(GameEngine game) {
        this.game = game;
    }
}
